#ifndef __CM_NAT_JINGLE_SESSION_H__
#define __CM_NAT_JINGLE_SESSION_H__

#include "Common.h"
#include "jid.h"
#include "Candidate.h"
#include "JingleSessionListener.h"

namespace cm_nat
{
    using namespace cm_xmpp;
    class JingleManager;

    class JingleSession
    {
    public:       
        JingleSession();
        virtual ~JingleSession();

        void setSessionID(std::string sid);
        void setJingleManager(JingleManager* p_manager);

        void setJID(JID jid);
        void setPeerJID(JID jid);

        virtual int initiate() = 0;
        virtual int accept() = 0;
        virtual int reject() = 0;
        virtual int terminate() = 0;

        virtual int parseJingleTag(const Tag* p_tag) = 0;

        enum SessionState {
            STATE_INIT = 0,
            STATE_SENTINITIATE,      // sent initiate, waiting for Accept or Reject
            STATE_RECEIVEDINITIATE,  // received an initiate. Call Accept or Reject
            STATE_SENTACCEPT,        // sent accept. begin connecting transport
            STATE_RECEIVEDACCEPT,    // received accept. begin connecting transport
            STATE_SENTMODIFY,        // sent modify, waiting for Accept or Reject
            STATE_RECEIVEDMODIFY,    // received modify, call Accept or Reject
            STATE_SENTREJECT,        // sent reject after receiving initiate
            STATE_RECEIVEDREJECT,    // received reject after sending initiate
            STATE_SENTREDIRECT,      // sent direct after receiving initiate
            STATE_SENTTERMINATE,     // sent terminate (any time / either side)
            STATE_RECEIVEDTERMINATE, // received terminate (any time / either side)
            STATE_INPROGRESS,        // session accepted and in progress
            STATE_DEINIT,            // session is being destroyed
        };
        enum ControlRole{
            CONTROLLING = 0,
            CONTROLLED    
        };

        static std::string generateSid();
    protected:
        std::string m_sid;

        JID m_jid;
        JID m_peerJid;

        SessionState  m_state;
        ControlRole m_role;

        CandidateList m_remoteCandidates;
        CandidateList m_localCandidates;

        JingleSessionListener* m_listener;

        JingleManager* m_jingleManager;

        friend class JingleManager;

    };

    typedef std::map<const std::string, JingleSession*>     JingleSessionIdMap;

}

#endif